<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
    <title>ShellCheck: SC2145 – Argument mixes string and array. Use `*` or separate argument.</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" />
  </head>
  <body style="margin-left: auto; margin-right: auto; max-width: 800px">
    <h1>SC2145 – ShellCheck Wiki</h1>
    <a href="https://github.com/koalaman/shellcheck/wiki/SC2145">See this page on GitHub</a>
    <p style="display: none"><a href="index.html">Sitemap</a></p>
    <hr />
    <h2
id="argument-mixes-string-and-array-use--or-separate-argument">Argument
mixes string and array. Use <code>*</code> or separate argument.</h2>
<h3 id="problematic-code">Problematic code:</h3>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="SC2145.html#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">printf</span> <span class="st">&quot;Error: %s\n&quot;</span> <span class="st">&quot;Bad parameters: </span><span class="va">$@</span><span class="st">&quot;</span></span></code></pre></div>
<h3 id="correct-code">Correct code:</h3>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="SC2145.html#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="bu">printf</span> <span class="st">&quot;Error: %s\n&quot;</span> <span class="st">&quot;Bad parameters: </span><span class="va">$*</span><span class="st">&quot;</span></span></code></pre></div>
<h3 id="problematic-code-2">Problematic code 2:</h3>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="SC2145.html#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="bu">printf</span> <span class="st">&quot;Error: %s\n&quot;</span> <span class="st">&quot;Bad parameters: </span><span class="va">${ARRAY_VAR</span><span class="op">[@]</span><span class="va">}</span><span class="st">&quot;</span></span></code></pre></div>
<h3 id="correct-code-2">Correct code 2:</h3>
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="SC2145.html#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="bu">printf</span> <span class="st">&quot;Error: %s\n&quot;</span> <span class="st">&quot;Bad parameters: &quot;</span> <span class="st">&quot;</span><span class="va">${ARRAY_VAR</span><span class="op">[@]</span><span class="va">}</span><span class="st">&quot;</span></span></code></pre></div>
<h3 id="rationale">Rationale:</h3>
<p>The behavior when concatenating a string and array is rarely
intended. The preceding string is prefixed to the first array element,
while the succeeding string is appended to the last one. The middle
array elements are unaffected.</p>
<p>E.g., with the parameters
<code>foo</code>,<code>bar</code>,<code>baz</code>,
<code>"--flag=$@"</code> is equivalent to the three arguments
<code>"--flag=foo" "bar" "baz"</code>.</p>
<p>If the intention is to concatenate all the array elements into one
argument, use <code>$*</code>. This concatenates based on
<code>IFS</code>.</p>
<p>If the intention is to provide each array element as a separate
argument, put the array expansion in its own argument.</p>
<h3 id="exceptions">Exceptions</h3>
<p>The POSIX specified behavior of <code>$@</code> (and by extension
arrays) as part of other strings is often unexpected:</p>
<blockquote>
<p>if the parameter being expanded was embedded within a word, the first
field shall be joined with the beginning part of the original word and
the last field shall be joined with the end part of the original word.
In all other contexts the results of the expansion are unspecified. If
there are no positional parameters, the expansion of '@' shall generate
zero fields, even when '@' is within double-quotes; however, if the
expansion is embedded within a word which contains one or more other
parts that expand to a quoted null string, these null string(s) shall
still produce an empty field, except that if the other parts are all
within the same double-quotes as the '@', it is unspecified whether the
result is zero fields or one empty field.</p>
</blockquote>
<p>If you're aware of this and intend to take advantage of it, you can
ignore this warning. However, you can also usually also rewrite it into
a less surprising form. For example, here's a wrapper script that uses
this behavior to substitute certain commands by defining a function for
them:</p>
<pre><code>#!/bin/sh
fixed_fgrep() { grep -F &quot;$@&quot;; }
fixed_echo() { printf &#39;%s\n&#39; &quot;$*&quot;; }
fixed_seq() { echo &quot;seq is not portable&quot; &gt;&amp;2; return 1; }

if command -v &quot;fixed_$1&quot; &gt; /dev/null 2&gt;&amp;1
then
  # shellcheck disable=SC2145   # I know how fixed_&quot;$@&quot; behaves and it&#39;s correct!
  fixed_&quot;$@&quot;
else
  &quot;$@&quot;
fi</code></pre>
<p>Here's the same script without relying on this behavior:</p>
<pre><code>#!/bin/sh
fixed_fgrep() { grep -F &quot;$@&quot;; }
fixed_echo() { printf &#39;%s\n&#39; &quot;$*&quot;; }
fixed_seq() { echo &quot;seq is not portable&quot; &gt;&amp;2; return 1; }

cmd=&quot;$1&quot;
shift

if command -v &quot;fixed_$cmd&quot; &gt; /dev/null 2&gt;&amp;1
then
 # Perhaps more straight forward with fewer surprises:
  &quot;fixed_$cmd&quot; &quot;$@&quot;
else
  &quot;$cmd&quot; &quot;$@&quot;
fi</code></pre>
    <hr />
    <p style='font-size: 80%'><a href="../index.html">ShellCheck</a> is a static analysis tool for shell scripts. This page is part of its documentation.</p>
  </body>
</html>


